#include "CenterFriendManager.h"
#include "StringConverter.h"
#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "json/json.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "Users.h"
#include "UserManager.h"
#include "ChannelManager.h"
#include "ItemModelManager.h"
#include "Message.h"
#include "CenterBankManager.h"
#include "VipCardManager.h"
#include "Tools.h"
#include "XMLData.h"
#include "GameDefine.h"
#include XMLDATA_MGR_PATH
#include LOGIC_MGR_PATH
#include LOG_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include "OpcodesEx.h"
#include "WorldPacket.h"

//--------------------------------------------------------
bool CenterFriendsManager::AddCenterGameFriend(CenterGameFriend & cGF)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, &fields);
	// sDataMgr.initData(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, &fields);
	
	// uint32 friend_id;						// 游戏好友ID
	fields["group_id"] = 1;						
	fields["type"] = cGF.type;					
	fields["flag"] = cGF.flag;					
	fields["status"] = cGF.status;				
	fields["category"] = cGF.category;			
	fields["create_gz_id"] = cGF.create_gz_id;
	fields["src_platform_id"] = cGF.src_platform_id;	
	fields["user_pid"] = cGF.user_pid;	
	fields["friend_user_pid"] = cGF.friend_user_pid;	
	fields["user_openid"] = cGF.user_openid;	
	fields["friend_user_openid"] = cGF.friend_user_openid;	
	fields["name"] = cGF.name;	
	fields["nick"] = cGF.nick;	
	fields["desc"] = cGF.desc;	
	fields["user_data"] = cGF.user_data;	
	fields["create_time"] = cGF.create_time;
	fields["ll_time"] = cGF.ll_time;
	
	fields["data1"] = cGF.data1;	
	fields["data2"] = cGF.data2;	
	fields["data3"] = cGF.data3;	
	fields["data4"] = cGF.data4;	
	fields["data5"] = cGF.data5;	
	fields["data6"] = cGF.data6;	
	fields["data7"] = cGF.data7;	
	fields["data8"] = cGF.data8;	
	fields["fdata1"] = cGF.fdata1;	
	fields["fdata2"] = cGF.fdata2;	
	fields["fdata3"] = cGF.fdata3;	
	fields["fdata4"] = cGF.fdata4;	
	
	fields["sdata1"] = cGF.sdata1;	
	fields["sdata2"] = cGF.sdata2;	
	fields["sdata3"] = cGF.sdata3;	
	fields["sdata4"] = cGF.sdata4;	
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, &fields))
	// if (!sDataMgr.insertData(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, &fields))
		return false;
	
	cGF.friend_id = fields["friend_id"].GetUInt32();
	
	return true;
}
//--------------------------------------------------------
bool CenterFriendsManager::UpdateCenterGameFriend(const CenterGameFriend & cGF)
{
	Fields fields;
	// fields["group_id"] = cGF.group_id;
	// fields["type"] = cGF.type;
	// fields["flag"] = cGF.flag;
	fields["status"] = cGF.status;
	// fields["category"] = cGF.category;
	
	// fields["create_gz_id"] = cGF.create_gz_id;
	// fields["src_platform_id"] = cGF.src_platform_id;
	// fields["user_pid"] = cGF.user_pid;
	// fields["friend_user_pid"] = cGF.friend_user_pid;
	
	// fields["user_openid"] = cGF.user_openid;
	// fields["friend_user_openid"] = cGF.friend_user_openid;
	// fields["name"] = cGF.name;
	// fields["nick"] = cGF.nick;
	// fields["desc"] = cGF.desc;
	fields["user_data"] = cGF.user_data;
	// fields["create_time"] = cGF.create_time;
	fields["ll_time"] = cGF.ll_time;
	
	fields["data1"] = cGF.data1;
	fields["data2"] = cGF.data2;
	fields["data3"] = cGF.data3;
	fields["data4"] = cGF.data4;
	fields["data5"] = cGF.data5;
	fields["data6"] = cGF.data6;
	fields["data7"] = cGF.data7;
	fields["data8"] = cGF.data8;
	fields["fdata1"] = cGF.fdata1;
	fields["fdata2"] = cGF.fdata2;
	fields["fdata3"] = cGF.fdata3;
	fields["fdata4"] = cGF.fdata4;
	fields["sdata1"] = cGF.sdata1;
	fields["sdata2"] = cGF.sdata2;
	fields["sdata3"] = cGF.sdata3;
	fields["sdata4"] = cGF.sdata4;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, &fields, "`friend_id` = %u", cGF.friend_id);
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, &fields, "`friend_id` = %u", cGF.friend_id);
	return count > 0;
}
#define SQLBUFER_LEN 16384
//--------------------------------------------------------
bool CenterFriendsManager::UpdateCenterGameFriend(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, fields, sql);
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, fields, sql);
	return count > 0;	
}
//--------------------------------------------------------
bool CenterFriendsManager::UpdateCenterGameFriend(const uint32 &cgf_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, fields, "`friend_id` = %u", cgf_id);
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, fields, "`friend_id` = %u", cgf_id);
	return count > 0;	
}
//--------------------------------------------------------
bool CenterFriendsManager::GetCenterGameFriend(const uint32 &cgf_id, CenterGameFriend * cgf)
{
	assert (cgf);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, &rows, "`friend_id` = %u", cgf_id);
	// sDataMgr.getDatas(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, &rows, "`friend_id` = %u", cgf_id);
	if (rows.empty())
		return false;
	Fields fields = rows.front();
	cgf->friend_id = fields["friend_id"].GetUInt32();
	cgf->group_id = fields["group_id"].GetUInt32();
	cgf->type = fields["type"].GetUInt32();
	cgf->flag = fields["flag"].GetUInt32();
	cgf->status = fields["status"].GetUInt32();
	cgf->category = fields["category"].GetUInt32();
	cgf->create_gz_id = fields["create_gz_id"].GetUInt32();
	
	cgf->src_platform_id = fields["src_platform_id"].GetUInt32();
	cgf->user_pid = fields["user_pid"].GetUInt32();
	cgf->friend_user_pid = fields["friend_user_pid"].GetUInt32();
	cgf->user_openid = fields["user_openid"].GetValue();
	cgf->friend_user_openid = fields["friend_user_openid"].GetValue();
	cgf->name = fields["name"].GetValue();
	cgf->nick = fields["nick"].GetValue();
	cgf->desc = fields["desc"].GetValue();
	cgf->user_data = fields["user_data"].GetValue();
	
	cgf->create_time = fields["create_time"].GetUInt32();
	cgf->ll_time = fields["ll_time"].GetUInt32();
	
	cgf->data1 = fields["data1"].GetUInt32();
	cgf->data2 = fields["data2"].GetUInt32();
	cgf->data3 = fields["data3"].GetUInt32();
	cgf->data4 = fields["data4"].GetUInt32();
	cgf->data5 = fields["data5"].GetInt32();
	cgf->data6 = fields["data6"].GetInt32();
	cgf->data7 = fields["data7"].GetInt32();
	cgf->data8 = fields["data8"].GetInt32();
	
	cgf->fdata1 = fields["fdata1"].GetFloat();
	cgf->fdata2 = fields["fdata2"].GetFloat();
	cgf->fdata3 = fields["fdata3"].GetFloat();
	cgf->fdata4 = fields["fdata4"].GetFloat();
	cgf->sdata1 = fields["sdata1"].GetValue();
	cgf->sdata2 = fields["sdata2"].GetValue();
	cgf->sdata3 = fields["sdata3"].GetValue();
	cgf->sdata4 = fields["sdata4"].GetValue();
	
	return true;
}

//--------------------------------------------------------
uint32 CenterFriendsManager::GetCenterGameFriendList(std::list<CenterGameFriend> * lstFriend, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstFriend->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_GAMEFRIEDN, &fieldRows, sql))
	// if (!sDataMgr.getDatas(DataManager::DatabaseTypeInfo, DB_NAME_GAMEFRIEDN, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		CenterGameFriend cgf;
		Fields &fields = *iter;
		
		cgf.friend_id = fields["friend_id"].GetUInt32();
		cgf.group_id = fields["group_id"].GetUInt32();
		cgf.type = fields["type"].GetUInt32();
		cgf.flag = fields["flag"].GetUInt32();
		cgf.status = fields["status"].GetUInt32();
		cgf.category = fields["category"].GetUInt32();
		cgf.create_gz_id = fields["create_gz_id"].GetUInt32();
		
		cgf.src_platform_id = fields["src_platform_id"].GetUInt32();
		cgf.user_pid = fields["user_pid"].GetUInt32();
		cgf.friend_user_pid = fields["friend_user_pid"].GetUInt32();
		cgf.user_openid = fields["user_openid"].GetValue();
		cgf.friend_user_openid = fields["friend_user_openid"].GetValue();
		cgf.name = fields["name"].GetValue();
		cgf.nick = fields["nick"].GetValue();
		cgf.desc = fields["desc"].GetValue();
		cgf.user_data = fields["user_data"].GetValue();
		
		cgf.create_time = fields["create_time"].GetUInt32();
		cgf.ll_time = fields["ll_time"].GetUInt32();
		
		cgf.data1 = fields["data1"].GetUInt32();
		cgf.data2 = fields["data2"].GetUInt32();
		cgf.data3 = fields["data3"].GetUInt32();
		cgf.data4 = fields["data4"].GetUInt32();
		cgf.data5 = fields["data5"].GetInt32();
		cgf.data6 = fields["data6"].GetInt32();
		cgf.data7 = fields["data7"].GetInt32();
		cgf.data8 = fields["data8"].GetInt32();
		
		cgf.fdata1 = fields["fdata1"].GetFloat();
		cgf.fdata2 = fields["fdata2"].GetFloat();
		cgf.fdata3 = fields["fdata3"].GetFloat();
		cgf.fdata4 = fields["fdata4"].GetFloat();
		cgf.sdata1 = fields["sdata1"].GetValue();
		cgf.sdata2 = fields["sdata2"].GetValue();
		cgf.sdata3 = fields["sdata3"].GetValue();
		cgf.sdata4 = fields["sdata4"].GetValue();
		
		lstFriend->push_back(cgf);
	}
	
	return lstFriend->size();
}

//==========================好友逻辑操作相关=================================
// 更新平台好友
bool CenterFriendsManager::UpdatePlatformFriends(CharPtr & pChr, const uint32 & gz_id ,std::list<String> vLFrdOpenid)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	// 得到玩家平台好友列表
	std::list<CenterGameFriend> lstFriend;
	GetCenterGameFriendList(&lstFriend, "user_pid = %u and type = %u and category = %u", pUser->getUInt32Field("platform_id"), en_FriendType_Platform, en_FriendType_Platform);
	
	std::list<uint32> vRemovePid;
	std::list<CenterGameFriend>::iterator itF,eiF = lstFriend.end();
	for(itF = lstFriend.begin(); itF!=eiF; ++itF)
	{
		bool bFindFriend = false;
		
		std::list<String>::iterator iter,ei = vLFrdOpenid.end();
		for(iter = vLFrdOpenid.begin(); iter!=ei; ++iter)
		{
			if(*iter == (*itF).friend_user_openid)
			{// 用来更新的好友列表中，找到原来的好友
				bFindFriend = true;
				vLFrdOpenid.erase(iter);
				break;
			}
		}
		
		if(!bFindFriend)
		{// 新列表中未找到原有好友，删除
			vRemovePid.push_back((*itF).friend_user_pid);
		}
	}
	
	if(vLFrdOpenid.size())
	{// 添加好友关系
		std::list<String>::iterator iter,ei = vLFrdOpenid.end();
		for(iter = vLFrdOpenid.begin(); iter!=ei; ++iter)
		{
			std::list<ResourcePtr> users;
			sUserMgr.getDBObjects(&users, 0, 1, "gz_id = %u and sdata1 = %s", gz_id, (*iter).c_str());
			if(users.empty())
				continue;
			
			ResourcePtr destUser = *users.begin();
			
			ResourcePtr destChar = sCharMgr.getDBObjectByHandle(destUser->getUInt32Field("userid"));
			if(destChar.isNull())
				continue;
			
			uint32 time_now = time(0);
			
			CenterGameFriend srcGF,destGF;
			srcGF.group_id = sChannelMgr.getGroupID();
			srcGF.type = en_FriendType_Platform;
			srcGF.status = enFriendStatus_BeingFriend;						//好友状态，申请好友
			srcGF.category = en_FriendType_Platform;
			srcGF.create_gz_id = pChr->getUInt32Field("gz_id");
			srcGF.user_pid = pUser->getUInt32Field("platform_id");
			srcGF.friend_user_pid = destUser->getUInt32Field("platform_id");
			srcGF.name = destChar->getStringField("name");					//昵称
			srcGF.desc = destChar->getStringField("desc");					//头像
			srcGF.user_openid = pUser->getStringField("sdata1");			//用户openid
			srcGF.friend_user_openid = destUser->getStringField("sdata1");	//好友openid
			srcGF.create_time = time_now;									// 创建时间
			srcGF.ll_time = time_now;										// 最后更新时间
			
			destGF.group_id = sChannelMgr.getGroupID();
			destGF.type = en_FriendType_Platform;
			destGF.status = enFriendStatus_BeingFriend;						//好友状态，等待添加
			destGF.category = en_FriendType_Platform;
			destGF.create_gz_id = destChar->getUInt32Field("gz_id");
			destGF.user_pid = destUser->getUInt32Field("platform_id");
			destGF.friend_user_pid = pUser->getUInt32Field("platform_id");
			destGF.name = pChr->getStringField("name");						//昵称
			destGF.desc = pChr->getStringField("desc");						//头像
			destGF.user_openid = destUser->getStringField("sdata1");		//用户openid
			destGF.friend_user_openid = pUser->getStringField("sdata1");	//好友openid
			destGF.create_time = time_now;									// 创建时间
			destGF.ll_time = time_now;										// 最后更新时间
			
			AddCenterGameFriend(srcGF);
			AddCenterGameFriend(destGF);
		}
	}
	
	if(vRemovePid.size())
	{// 删除已有好友关系
		
		std::list<uint32>::iterator itRemove,eiRemove = vRemovePid.end();
		for(itRemove = vRemovePid.begin(); itRemove!=eiRemove; ++itRemove)
		{
			CenterGameFriend srcFriend,destFriend;
			
			std::list<CenterGameFriend> lstFriend;
			GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
								pUser->getUInt32Field("platform_id"), *itRemove, en_FriendType_Platform);
			if(lstFriend.empty())
				continue;
			
			srcFriend = *lstFriend.begin();
			
			lstFriend.clear();
			GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
								*itRemove, pUser->getUInt32Field("platform_id"), en_FriendType_Platform);
			if(lstFriend.empty())
				continue;
			
			destFriend = *lstFriend.begin();
			
			srcFriend.status = enFriendStatus_Delete;
			destFriend.status = enFriendStatus_Delete;
			
			UpdateCenterGameFriend(srcFriend);
			UpdateCenterGameFriend(destFriend);
		}
		
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateUpdateCenterPlatformFriendPacket(&packet,enCFPR_Sucess))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	// 发送新好友列表给玩家
	GetFriendListInfo(pChr, enFriendListType_Require);
	GetFriendListInfo(pChr, enFriendListType_Friends);
	return true;
}

// 好友数据更新（找到加为好友的其他人，更新他们的好友数据） 
bool CenterFriendsManager::UpdateFriendData(CharPtr & pChr,Fields * fields)
{
	
	
	
	return true;
}

// 好友列表信息
void CenterFriendsManager::GetFriendListInfo(CharPtr & pChr, const uint32 & type)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	std::list<CenterGameFriend> lstFriend;
	
	if(type == enFriendListType_Require)
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and status = %u and type = %u", pUser->getUInt32Field("platform_id"), enFriendStatus_WaitAdd, en_FriendType_Game);
	else if(type == enFriendListType_Friends)
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and status = %u and type = %u", pUser->getUInt32Field("platform_id"), enFriendStatus_BeingFriend, en_FriendType_Game);
	
	//发送好友消息给玩家
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterFriendListPacket(&packet, type, lstFriend))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 系统推荐好友列表
void CenterFriendsManager::GetSystemFriends(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	// 判断玩家好友上限，不推荐系统好友给他
	
	uint32 agent_id = pUser->getUInt32Field("reg_from");
	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 op_count = 0;
	uint32 db_count = sUserMgr.getDBCount("platform_id < %u and reg_from = %u", pid, agent_id);
	
	std::list<CenterGameFriend> lstMyFriend;
	GetCenterGameFriendList(&lstMyFriend, "user_pid = %u and type = %u and status <= %u", pid, en_FriendType_Game, enFriendStatus_BeingFriend);
	
	std::list<ResourcePtr> lstSysFriend;
	std::map<uint32, uint32> mapSysFriends;
	while(mapSysFriends.size() < 3)
	{
		if(op_count >= 10)
			break;
		
		++op_count;
		
		std::list<ResourcePtr> users;
		sUserMgr.getDBObjects(&users, RandomUInt(db_count), 1, "platform_id < %u and reg_from = %u", pid, agent_id);
		if(users.empty())
			continue;
		
		ResourcePtr pFrdUser = *users.begin();
		if(pFrdUser.isNull())
			continue;
		
		uint32 frd_pid = pFrdUser->getUInt32Field("platform_id");
		
		bool bExit = false;
		std::list<CenterGameFriend>::iterator itFrd, eiFrd = lstMyFriend.end();
		for(itFrd = lstMyFriend.begin(); itFrd!=eiFrd; ++itFrd)
		{
			if((*itFrd).friend_user_pid == frd_pid)
			{
				bExit = true;
				break;
			}
		}
		
		if(bExit)
			continue;
		
		std::map<uint32, uint32>::iterator fit = mapSysFriends.find(frd_pid);
		if(fit == mapSysFriends.end())
		{// 添加好友
			mapSysFriends.insert(std::make_pair(frd_pid, 1));
			lstSysFriend.push_back(pFrdUser);
		}
		else
		{// 已经添加
			continue;
		}
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterSystemFriendListPacket(&packet, lstSysFriend))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 查看好友信息
void CenterFriendsManager::LookFriendInfo(CharPtr & pChr,const uint32 & friend_pid)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	std::list<CenterGameFriend> lstFriend;
	GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", pUser->getUInt32Field("platform_id"), friend_pid, en_FriendType_Game);
	if(lstFriend.empty())
		return ;
	
	CenterGameFriend stFriend = *lstFriend.begin();
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet, stFriend, enFriendLookType_LookOrUpdate))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 查看好友信息
void CenterFriendsManager::LookFriendInfo(CharPtr & pChr,String openid)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	// 通过openid获得数据
	std::list<CenterGameFriend> lstFriend;
	GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_openid = %s and type = %u and status < 255", pUser->getUInt32Field("platform_id"), openid.c_str(), en_FriendType_Game);
	if(lstFriend.empty())
		return ;
	
	CenterGameFriend stFriend = *lstFriend.begin();
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet, stFriend, enFriendLookType_LookOrUpdate))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 添加好友
bool CenterFriendsManager::RequireFriend(CharPtr & srcChar,const uint32 & dest_pid)
{
	if(srcChar.isNull() || !dest_pid)
		return false;
	
	UserPtr srcUser = sUserMgr.getByHandle(srcChar->getUInt32Field("userid"));
	if(srcUser.isNull())
		return false;
	
	UserPtr destUser;
	bool bContinueAdd = false;
	CharPtr destChar;
	
	uint8 result = enCFPR_Sucess;
	std::list<CenterGameFriend> lstFriend;
	CenterGameFriend srcFriend;
	CenterGameFriend destFriend;
	
	do
	{
		if(dest_pid == srcUser->getUInt32Field("platform_id"))
		{
			result = enCPFR_OP_CannotOpSelf;
			break;
		}
		
		std::list<UserPtr> lstUser;
		sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u and gz_id = %u", dest_pid, srcUser->getUInt32Field("gz_id"));
		
		if(lstUser.empty())
		{// 目标玩家不在线或者不存在
			result = enCPFR_OP_FriendOffline;
			break;
		}
		
		destUser = *lstUser.begin();
		if(destUser.isNull())
		{// 用户不在线或者没有该用户
			result = enCPFR_OP_FriendOffline;
			break;
		}
		
		destChar = sCharMgr.load(destUser->getUInt32Field("char_id"));
		if(destChar.isNull())
		{
			result = enCPFR_OP_FriendOffline;
			break;
		}
		
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										srcUser->getUInt32Field("platform_id"), destUser->getUInt32Field("platform_id"), en_FriendType_Game);
		
		if(lstFriend.size())
		{// 不是对方申请，等待自己
			
			srcFriend = *lstFriend.begin();
			if(srcFriend.status != enFriendStatus_WaitAdd)
			{
				result = enCPFR_OP_AlreadyFriends;
				break;
			}
		}
		
		lstFriend.clear();
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
						destUser->getUInt32Field("platform_id"), srcUser->getUInt32Field("platform_id"), en_FriendType_Game);
		if(lstFriend.size())
		{// 对方发出的好友邀请，直接添加成功
			
			destFriend = *lstFriend.begin();
			if(destFriend.status == enFriendStatus_WaitAdd)
			{// 对方发出过好友申请
				bContinueAdd = true;
				break;
			}
			else if(destFriend.status != enFriendStatus_Delete)
			{// 已经是好友关系
				result = enCPFR_OP_AlreadyFriends;
				break;
			}
		}
		
		std::list<CenterGameFriend> lstWantFriend;
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and type = %u and status = %u", 
							destUser->getUInt32Field("platform_id"), en_FriendType_Game, enFriendStatus_WaitAdd);
		
		if(lstWantFriend.size() >= sXmlDataMgr.GetConfXMLValue("MAX_REQUIRE_FRIEND_NUM"))
		{// 被申请玩家申请列表已满
			result = enCPFR_OP_RequireListFull;
			break;
		}
	}while(0);
	
	// 发包操作结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterOperatorFriendPacket(&packet, dest_pid, enOperatorFriend_Add, result))
		sGLMgr.SendProtocolsToChr(srcChar,&packet);
	
	if(result == enCFPR_Sucess)
	{
		if(bContinueAdd)
		{// 同意玩家加为好友
			srcFriend.status = enFriendStatus_BeingFriend;
			destFriend.status = enFriendStatus_BeingFriend;
			
			// 更新彼此好友信息
			if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,srcFriend,enFriendLookType_LookOrUpdate))
				sGLMgr.SendProtocolsToChr(srcChar,&packet);
			if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,destFriend,enFriendLookType_LookOrUpdate))
				sGLMgr.SendProtocolsToChr(destChar,&packet);
		}
		else
		{// 申请加玩家为好友
			uint32 time_now = time(0);
			
			CenterGameFriend srcGF,destGF;
			srcGF.group_id = sChannelMgr.getGroupID();
			srcGF.type = en_FriendType_Game;
			srcGF.status = enFriendStatus_Require;		// 好友状态，申请好友
			srcGF.flag = enFriendGameStatus_Init;		// 初始
			srcGF.category = en_FriendType_Game;
			srcGF.create_gz_id = srcChar->getUInt32Field("gz_id");
			srcGF.user_pid = srcUser->getUInt32Field("platform_id");
			srcGF.friend_user_pid = destUser->getUInt32Field("platform_id");
			srcGF.user_openid = srcUser->getStringField("sdata1");
			srcGF.friend_user_openid = destUser->getStringField("sdata1");
			srcGF.name = destChar->getStringField("name");		//昵称
			srcGF.desc = destChar->getStringField("desc");		//头像
			srcGF.create_time = time_now;				// 创建时间
			srcGF.ll_time = time_now;					// 最后更新时间
			
			destGF.group_id = sChannelMgr.getGroupID();
			destGF.type = en_FriendType_Game;
			destGF.status = enFriendStatus_WaitAdd;		//好友状态，等待添加
			destGF.flag = enFriendGameStatus_Init;		// 初始
			destGF.category = en_FriendType_Game;
			destGF.create_gz_id = destChar->getUInt32Field("gz_id");
			destGF.user_pid = destUser->getUInt32Field("platform_id");
			destGF.friend_user_pid = srcUser->getUInt32Field("platform_id");
			destGF.user_openid = destUser->getStringField("sdata1");
			destGF.friend_user_openid = srcUser->getStringField("sdata1");
			destGF.name = srcChar->getStringField("name");		//昵称
			destGF.desc = srcChar->getStringField("desc");		//头像
			destGF.create_time = time_now;						// 创建时间
			destGF.ll_time = time_now;							// 最后更新时间
			
			AddCenterGameFriend(srcGF);
			AddCenterGameFriend(destGF);
			
			// 更新彼此好友信息
			// if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet, srcGF, enOperatorFriend_Add))
				// sGLMgr.SendProtocolsToChr(srcChar,&packet);
			if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet, destGF, enOperatorFriend_Add))
				sGLMgr.SendProtocolsToChr(destChar,&packet);
			GetFriendListInfo(destChar, enFriendListType_Require);
			
			Log.Debug("CenterFriendsManager::RequireFriend","destChar id[%u]", destChar->getHandle());
		}
	}
	
	if(!destChar.isNull())
		Log.Debug("CenterFriendsManager::RequireFriend","char[%u] sucess require friend char[%u]!",srcChar->getHandle(), destChar->getHandle());
	
	return true;
}

// 同意或拒绝添加好友
bool CenterFriendsManager::AnswerAddFriend(CharPtr & pChr, const uint32 & require_pid, const uint8 & opType)
{
	if(opType != enOperatorFriend_Apply && opType != enOperatorFriend_Refuse)
		return false;
	
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", require_pid, gz_id);
	if (lstUser.empty())
		return false;
	
	UserPtr destUser = lstUser.front();
	if(destUser.isNull())
		return false;
	
	CharPtr destChar = sCharMgr.load(destUser->getUInt32Field("char_id"));
	if(destChar.isNull())
		return false;
	
	uint8 result = enCFPR_Sucess;
	CenterGameFriend srcFriend,destFriend;
	
	do
	{
		std::list<CenterGameFriend> lstFriend;
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										pUser->getUInt32Field("platform_id"),destUser->getUInt32Field("platform_id"), en_FriendType_Game);
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		srcFriend = *lstFriend.begin();
		if(srcFriend.status != enFriendStatus_WaitAdd)
		{
			result = enCPFR_OP_ErrorStatus;
			break;
		}
		
		lstFriend.clear();
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										destUser->getUInt32Field("platform_id"),pUser->getUInt32Field("platform_id"), en_FriendType_Game);
		
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		destFriend = *lstFriend.begin();
		if(destFriend.status != enFriendStatus_Require)
		{
			result = enCPFR_OP_ErrorStatus;
			break;
		}
		
	}while(0);
	
	// 发送操作结果 2 同意 3 拒绝
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterOperatorFriendPacket(&packet, destUser->getUInt32Field("platform_id"), opType, result))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	if(result == enCFPR_Sucess)
	{
		uint8 friend_opType = enFriendLookType_LookOrUpdate;
		if(opType == enOperatorFriend_Apply)
		{// 同意
			srcFriend.status = enFriendStatus_BeingFriend;
			destFriend.status = enFriendStatus_BeingFriend;
		}
		else if(opType == enOperatorFriend_Refuse)
		{// 拒绝
			srcFriend.status = enFriendStatus_Delete;
			destFriend.status = enFriendStatus_Delete;
			
			friend_opType = enFriendLookType_Delete;
		}
		
		UpdateCenterGameFriend(srcFriend);
		UpdateCenterGameFriend(destFriend);
		
		// 更新彼此好友信息
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,srcFriend,friend_opType))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,destFriend,friend_opType))
			sGLMgr.SendProtocolsToChr(destChar,&packet);
	}
	
	return true;
}

// 删除好友
bool CenterFriendsManager::DeleteFriend(CharPtr & pChr,const uint32 & friend_pid)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", friend_pid, gz_id);
	if (lstUser.empty())
		return false;
	
	UserPtr destUser = lstUser.front();
	if(destUser.isNull())
		return false;
	
	CharPtr destChar = sCharMgr.load(destUser->getUInt32Field("char_id"));
	if(destChar.isNull())
		return false;
	
	uint8 result = enCFPR_Sucess;
	CenterGameFriend srcFriend,destFriend;
	
	do
	{
		std::list<CenterGameFriend> lstFriend;
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										pUser->getUInt32Field("platform_id"), destUser->getUInt32Field("platform_id"), en_FriendType_Game);
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		srcFriend = *lstFriend.begin();
		
		lstFriend.clear();
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										destUser->getUInt32Field("platform_id"), pUser->getUInt32Field("platform_id"), en_FriendType_Game);
		
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		destFriend = *lstFriend.begin();
		
	}while(0);
	
	// 发送操作结果 2 同意 3 拒绝
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterOperatorFriendPacket(&packet, friend_pid, enOperatorFriend_Delete, result))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	if(result == enCFPR_Sucess)
	{
		srcFriend.status = enFriendStatus_Delete;
		destFriend.status = enFriendStatus_Delete;
		
		UpdateCenterGameFriend(srcFriend);
		UpdateCenterGameFriend(destFriend);
		
		// 更新彼此好友信息
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,srcFriend,enFriendLookType_Delete))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,destFriend,enFriendLookType_Delete))
			sGLMgr.SendProtocolsToChr(destChar,&packet);
		GetFriendListInfo(destChar, enFriendListType_Friends);
	}
	
	return true;
}

// 拉黑好友（可以实现）
bool CenterFriendsManager::BlackFriend(CharPtr & pChr,const uint32 & friend_pid)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", friend_pid, gz_id);
	if (lstUser.empty())
		return false;
	
	UserPtr destUser = lstUser.front();
	if(destUser.isNull())
		return false;
	
	CharPtr destChar = sCharMgr.load(destUser->getUInt32Field("char_id"));
	if(destChar.isNull())
		return false;
	
	uint8 result = enCFPR_Sucess;
	CenterGameFriend srcFriend,destFriend;
	
	do
	{
		std::list<CenterGameFriend> lstFriend;
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										pUser->getUInt32Field("platform_id"), destUser->getUInt32Field("platform_id"), en_FriendType_Game);
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		srcFriend = *lstFriend.begin();
		
		lstFriend.clear();
		GetCenterGameFriendList(&lstFriend, "user_pid = %u and friend_user_pid = %u and type = %u and status < 255", 
										destUser->getUInt32Field("platform_id"), pUser->getUInt32Field("platform_id"), en_FriendType_Game);
		
		if(lstFriend.empty())
		{
			result = enCPFR_OP_NoFriendInfo;
			break;
		}
		
		destFriend = *lstFriend.begin();
		
	}while(0);
	
	// 发送操作结果 2 同意 3 拒绝
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterOperatorFriendPacket(&packet, friend_pid, enOperatorFriend_Delete, result))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	if(result == enCFPR_Sucess)
	{
		srcFriend.status = enFriendStatus_Delete;
		destFriend.status = enFriendStatus_Delete;
		
		UpdateCenterGameFriend(srcFriend);
		UpdateCenterGameFriend(destFriend);
		
		// 更新彼此好友信息
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,srcFriend,enFriendLookType_Delete))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
		if(sProtocolsMgr.CreateCenterFriendInfoPacket(&packet,destFriend,enFriendLookType_Delete))
			sGLMgr.SendProtocolsToChr(destChar,&packet);
	}
	
	return true;
}

// 更新好友游戏状态
bool CenterFriendsManager::UpdateFriendGameStatus(CharPtr & pChr, const uint32 & status, bool bForceUpdate)
{
	if(pChr.isNull())
		return false;
	
	// Log.Debug("CenterFriendsManager::UpdateFriendGameStatus","===========================================1");
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	// Log.Debug("CenterFriendsManager::UpdateFriendGameStatus","===========================================2");
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	// 获取自己的好友状态信息
	std::list<CenterGameFriend> lstFriend;
	GetCenterGameFriendList(&lstFriend, "user_pid = %u and type = %u and status < 255 limit 0, 1", pid, en_FriendType_System);
	
	CenterGameFriend CGF;
	if(lstFriend.size())
	{// 更新好友自身状态
		CGF = *lstFriend.begin();
		// Log.Debug("CenterFriendsManager::UpdateFriendGameStatus","===========================================3");
		CGF.name = pChr->getStringField("name");
		CGF.desc = pChr->getStringField("desc");
		if(bForceUpdate)
		{
			CGF.flag = status;
		}
		else
		{
			if(CGF.flag != enFriendGameStatus_Game)
			{// 不在游戏中可随意更新玩家状态
				CGF.flag = status;
			}
		}
		
		CGF.ll_time = time(0);
		UpdateCenterGameFriend(CGF);
	}
	else
	{// 创建好友自身状态
		CGF.group_id = sChannelMgr.getGroupID();
		CGF.type = en_FriendType_System;
		CGF.flag = status;
		CGF.category = en_FriendType_System;
		CGF.create_gz_id = pChr->getUInt32Field("gz_id");
		CGF.user_pid = pUser->getUInt32Field("platform_id");
		CGF.name = pChr->getStringField("name");
		CGF.desc = pChr->getStringField("desc");
		CGF.create_time = time(0);
		CGF.ll_time = time(0);
		// Log.Debug("CenterFriendsManager::UpdateFriendGameStatus","===========================================4");
		AddCenterGameFriend(CGF);
	}
	
	// 更新他和其他好友关系中的状态
	Fields fields;
	fields["flag"] = status;
	UpdateCenterGameFriend(&fields, "`friend_user_pid` = %u and `status` < 255 and `flag` = %u and `type` = %u", pid, status, en_FriendType_System);
	// Log.Debug("CenterFriendsManager::UpdateFriendGameStatus","===========================================5");
	return true;
}

//==========================好友逻辑操作相关=================================


//=====================================好友分组==========================================
//--------------------------------------------------------
bool FriendCategoryManager::AddCenterFriendCategory(CenterFriendCategory & cFC)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, &fields);
	
	// uint32 cate_id;				
	fields["group_id"] = 1;						
	fields["pid"] = cFC.pid;					
	fields["openid"] = cFC.openid;
	fields["name"] = cFC.name;
	fields["desc"] = cFC.desc;	
	
	fields["create_time"] = cFC.create_time;
	fields["flag"] = cFC.flag;		
	fields["status"] = cFC.status;
	
	fields["data1"] = cFC.data1;			
	fields["data2"] = cFC.data2;
	fields["data3"] = cFC.data3;	
	fields["data4"] = cFC.data4;
	fields["fdata1"] = cFC.fdata1;
	fields["fdata2"] = cFC.fdata2;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, &fields))
		return false;
	
	cFC.cate_id = fields["cate_id"].GetUInt32();
	return true;
}
//--------------------------------------------------------
bool FriendCategoryManager::UpdateCenterFriendCategory(const CenterFriendCategory & cFC)
{
	Fields fields;
	// fields["group_id"] = 1;						
	// fields["pid"] = cFC.pid;
	// fields["openid"] = cFC.openid;
	// fields["name"] = cFC.name;
	// fields["desc"] = cFC.desc;	
	
	// fields["create_time"] = cFC.create_time;
	// fields["flag"] = cFC.flag;		
	fields["status"] = cFC.status;
	
	fields["data1"] = cFC.data1;			
	fields["data2"] = cFC.data2;
	fields["data3"] = cFC.data3;	
	fields["data4"] = cFC.data4;
	fields["fdata1"] = cFC.fdata1;
	fields["fdata2"] = cFC.fdata2;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, &fields, "`friend_id` = %u", cFC.cate_id);
	return count > 0;
}
#define SQLBUFER_LEN 16384
//--------------------------------------------------------
bool FriendCategoryManager::UpdateCenterFriendCategory(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, fields, sql);
	return count > 0;	
}

//--------------------------------------------------------
bool FriendCategoryManager::UpdateCenterFriendCategory(const uint32 &cfc_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, fields, "`cate_id` = %u", cfc_id);
	return count > 0;	
}

//--------------------------------------------------------
bool FriendCategoryManager::GetCenterFriendCategory(const uint32 &cgf_id, CenterFriendCategory * cFC)
{
	assert (cFC);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, &rows, "`friend_id` = %u", cgf_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cFC->cate_id = fields["cate_id"].GetUInt32();
	cFC->group_id = fields["group_id"].GetUInt32();
	cFC->pid = fields["pid"].GetUInt32();
	cFC->openid = fields["openid"].GetValue();
	cFC->name = fields["name"].GetValue();
	cFC->desc = fields["desc"].GetValue();
	
	cFC->create_time = fields["create_time"].GetUInt32();
	cFC->flag = fields["flag"].GetUInt32();
	cFC->status = fields["status"].GetUInt32();
	
	cFC->data1 = fields["data1"].GetUInt32();
	cFC->data2 = fields["data2"].GetUInt32();
	cFC->data3 = fields["data3"].GetInt32();
	cFC->data4 = fields["data4"].GetInt32();
	cFC->fdata1 = fields["fdata1"].GetFloat();
	cFC->fdata1 = fields["fdata1"].GetFloat();
	
	return true;
}

//--------------------------------------------------------
uint32 FriendCategoryManager::GetCenterFriendCategoryList(std::list<CenterFriendCategory> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_FRIENDCATEGORY, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		CenterFriendCategory cFC;
		Fields &fields = *iter;
		
		cFC.cate_id = fields["cate_id"].GetUInt32();
		cFC.group_id = fields["group_id"].GetUInt32();
		cFC.pid = fields["pid"].GetUInt32();
		cFC.openid = fields["openid"].GetValue();
		cFC.name = fields["name"].GetValue();
		cFC.desc = fields["desc"].GetValue();
		
		cFC.create_time = fields["create_time"].GetUInt32();
		cFC.flag = fields["flag"].GetUInt32();
		cFC.status = fields["status"].GetUInt32();
		
		cFC.data1 = fields["data1"].GetUInt32();
		cFC.data2 = fields["data2"].GetUInt32();
		cFC.data3 = fields["data3"].GetInt32();
		cFC.data4 = fields["data4"].GetInt32();
		cFC.fdata1 = fields["fdata1"].GetFloat();
		cFC.fdata1 = fields["fdata1"].GetFloat();
		
		lstData->push_back(cFC);
	}
	
	return lstData->size();
}

// 创建分组
bool FriendCategoryManager::CreateFriendCategory(CharPtr & pChr, String name)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint8 result = enCFPR_Sucess;
	
	do
	{	
		std::list<CenterFriendCategory> lstData;
		GetCenterFriendCategoryList(&lstData, "status < 255 and name = '%s' ", name.c_str());
		
		if(lstData.size())
		{// 已经创建
			result = enOpFriendCate_AlreadyCreated;
			break;
		}
		
		// 如果没有先判断是否达到创建上线
		
		
	}
	while(0);
	
	// 发送结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterFriendCategoryOperatorResultPacket(&packet, enOperatorFriendCateType_CreateNew, result))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	
	if(enCFPR_Sucess)
	{// 成功创建数据
		
		
	}
	
	return true;
}

// 删除分组
bool FriendCategoryManager::DeleteFriendCategory(CharPtr & pChr, const uint32 & cate_id)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint8 result = enCFPR_Sucess;
	CenterFriendCategory cfc;
	do
	{
		std::list<CenterFriendCategory> lstData;
		GetCenterFriendCategoryList(&lstData, "status < 255 and cate_id = %u", cate_id);
		
		if(lstData.empty())
		{// 未找到此分组
			result = enOpFriendCate_NoThisCate;
			break;
		}
		
		cfc = *lstData.begin();
		if(cfc.pid != pUser->getUInt32Field("platform_id"))
		{// 不是你的分组
			result = enOpFriendCate_NotYours;
			break;
		}
	}
	while(0);
	
	// 发送结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterFriendCategoryOperatorResultPacket(&packet, enOperatorFriendCateType_Delete, result))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	if(result == enCFPR_Sucess)
	{// 成功，添加数据
		cfc.status = 255;
		UpdateCenterFriendCategory(cfc);
	}
	
	return true;
}

//=============================好友记录信息相关===================================
bool FriendGameRecordsManager::AddCenterFriendRecord(CenterFriendRecord & cFR)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fields);
				
	fields["group_id"] = 1;						
	fields["status"] = cFR.status;					
	fields["pid"] = cFR.pid;					
	fields["openid"] = cFR.openid;	
	fields["gz_id"] = cFR.gz_id;
	fields["lu_timer"] = cFR.lu_timer;	
	fields["record_data"] = cFR.record_data;
	
	fields["data1"] = cFR.data1;		
	fields["data2"] = cFR.data2;
	fields["data3"] = cFR.data3;
	fields["data4"] = cFR.data4;
	fields["data5"] = cFR.data5;
	fields["data6"] = cFR.data6;
	fields["data7"] = cFR.data7;
	fields["data8"] = cFR.data8;
	
	fields["fdata1"] = cFR.fdata1;			
	fields["fdata2"] = cFR.fdata2;
	fields["sdata1"] = cFR.sdata1;	
	fields["sdata2"] = cFR.sdata2;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fields))
		return false;
	
	cFR.record_id = fields["record_id"].GetUInt32();
	return true;
}


bool FriendGameRecordsManager::UpdateCenterFriendRecord(const CenterFriendRecord & cFR)
{
	Fields fields;
	// fields["group_id"] = 1;						
	fields["status"] = cFR.status;					
	// fields["pid"] = cFR.pid;					
	// fields["openid"] = cFR.openid;	
	// fields["gz_id"] = cFR.gz_id;
	fields["lu_timer"] = cFR.lu_timer;	
	fields["record_data"] = cFR.record_data;
	
	fields["data1"] = cFR.data1;
	fields["data2"] = cFR.data2;
	fields["data3"] = cFR.data3;
	fields["data4"] = cFR.data4;
	fields["data5"] = cFR.data5;
	fields["data6"] = cFR.data6;
	fields["data7"] = cFR.data7;
	fields["data8"] = cFR.data8;
	
	fields["fdata1"] = cFR.fdata1;			
	fields["fdata2"] = cFR.fdata2;
	fields["sdata1"] = cFR.sdata1;
	fields["sdata2"] = cFR.sdata2;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fields, "`record_id` = %u", cFR.record_id);
	return count > 0;
}


bool FriendGameRecordsManager::UpdateCenterFriendRecord(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, fields, sql);
	return count > 0;
}

bool FriendGameRecordsManager::UpdateCenterFriendRecord(const uint32 &cfr_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, fields, "`record_id` = %u", cfr_id);
	return count > 0;
}


bool FriendGameRecordsManager::GetCenterFriendRecord(const uint32 &cfr_id, CenterFriendRecord * cFR)
{
	assert (cFR);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &rows, "`record_id` = %u", cfr_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cFR->record_id = fields["record_id"].GetUInt32();
	cFR->group_id = fields["group_id"].GetUInt32();
	cFR->status = fields["status"].GetUInt32();
	cFR->pid = fields["pid"].GetUInt32();
	cFR->openid = fields["openid"].GetValue();
	cFR->gz_id = fields["gz_id"].GetUInt32();
	cFR->lu_timer = fields["lu_timer"].GetUInt32();
	cFR->record_data = fields["record_data"].GetValue();
	
	cFR->data1 = fields["data1"].GetUInt32();
	cFR->data2 = fields["data2"].GetUInt32();
	cFR->data3 = fields["data3"].GetUInt32();
	cFR->data4 = fields["data4"].GetUInt32();
	cFR->data5 = fields["data5"].GetUInt32();
	cFR->data6 = fields["data6"].GetUInt32();
	cFR->data7 = fields["data7"].GetUInt32();
	cFR->data8 = fields["data8"].GetUInt32();
	
	cFR->fdata1 = fields["fdata1"].GetFloat();
	cFR->fdata1 = fields["fdata1"].GetFloat();
	cFR->sdata1 = fields["sdata1"].GetValue();
	cFR->sdata2 = fields["sdata2"].GetValue();
	return true;
}


uint32 FriendGameRecordsManager::GetCenterFriendRecordList(std::list<CenterFriendRecord> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		CenterFriendRecord cFR;
		Fields &fields = *iter;
		
		cFR.record_id = fields["record_id"].GetUInt32();
		cFR.group_id = fields["group_id"].GetUInt32();
		cFR.status = fields["status"].GetUInt32();
		cFR.pid = fields["pid"].GetUInt32();
		cFR.openid = fields["openid"].GetValue();
		cFR.gz_id = fields["gz_id"].GetUInt32();
		cFR.lu_timer = fields["lu_timer"].GetUInt32();
		cFR.record_data = fields["record_data"].GetValue();
		
		cFR.data1 = fields["data1"].GetUInt32();
		cFR.data2 = fields["data2"].GetUInt32();
		cFR.data3 = fields["data3"].GetUInt32();
		cFR.data4 = fields["data4"].GetUInt32();
		cFR.data5 = fields["data5"].GetUInt32();
		cFR.data6 = fields["data6"].GetUInt32();
		cFR.data7 = fields["data7"].GetUInt32();
		cFR.data8 = fields["data8"].GetUInt32();
		
		cFR.fdata1 = fields["fdata1"].GetFloat();
		cFR.fdata1 = fields["fdata1"].GetFloat();
		cFR.sdata1 = fields["sdata1"].GetValue();
		cFR.sdata2 = fields["sdata2"].GetValue();
		
		lstData->push_back(cFR);
	}
	
	return lstData->size();
}

// 提交记录数据
bool FriendGameRecordsManager::CommitPlayerInfoToCenter(CharPtr & pChr, String & sInfo, const uint8 & mode)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint8 real_mode = mode % 100;
	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<CenterFriendRecord> lstData;
	GetCenterFriendRecordList(&lstData,"gz_id = %u and data1 = %u and pid = %u and status < 255", gz_id, real_mode, pid);
	
	uint8 op_type = enCommitInfo_Create;	// 1 创建 2 更新
	uint8 result = 1;
	if(lstData.empty())
	{// 创建并提交记录
		CenterFriendRecord cFR;
		
		cFR.group_id = sChannelMgr.getGroupID();
		cFR.status = 1;
		cFR.pid = pid;
		cFR.gz_id = gz_id;
		cFR.data1 = real_mode;
		cFR.lu_timer = time(0);
		cFR.record_data = sInfo;
		
		result = AddCenterFriendRecord(cFR);
	}
	else
	{// 更新记录
		op_type = enCommitInfo_Update;
		
		CenterFriendRecord cFR = *lstData.begin();
		cFR.lu_timer = time(0);
		cFR.record_data = sInfo;
		
		result = UpdateCenterFriendRecord(cFR);
	}
	
	// 发送操作结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateCommitCenterPlayerInfoPacket(&packet,op_type,result))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 提交一场最终结果数据
bool FriendGameRecordsManager::CommitFinalCenterBattleData(CharPtr & pChr, const uint8 & mode, const uint32 & game_id, int32 & final_winlose)
{
	if(pChr.isNull())
		return false;
	
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint8 real_mode = mode % 100;
	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<CenterFriendRecord> lstData;
	GetCenterFriendRecordList(&lstData,"gz_id = %u and data1 = %u and pid = %u and status < 255", gz_id, real_mode, pid);
	
	if(lstData.empty())
		return false;
	
	CenterFriendRecord cFR = *lstData.begin();
	cFR.data2 = cFR.data2 + 1;							// 游戏总场次
	if(final_winlose > 0)
	{
		cFR.data3 = cFR.data3 + 1;						// 获胜场次
		cFR.data5 = cFR.data5 + uint32(final_winlose);	// 总赢取
	}
	
	cFR.data4 = game_id;								// 游戏ID
	
	float win_percent = float(cFR.data3) / float(cFR.data2);	// 胜率
	float aver_winScore = float(cFR.data5) / float(cFR.data2);	// 平均赢取
	
	cFR.fdata1 = win_percent;
	cFR.fdata2 = aver_winScore;
	cFR.lu_timer = time(0);
	
	UpdateCenterFriendRecord(cFR);
	return true;
}

// 读取记录数据
bool FriendGameRecordsManager::GetPlayerCenterInfo(CharPtr & pChr, const uint32 & pid, const uint32 & gz_id, const uint8 & mode)
{
	if(pChr.isNull())
		return false;
	
	uint8 real_mode = mode % 100;
	
	std::list<CenterFriendRecord> lstData;
	if(gz_id && real_mode)
	{
		GetCenterFriendRecordList(&lstData,"gz_id = %u and data1 = %u and  pid = %u and status < 255",gz_id, real_mode, pid);
	}
	else
	{
		GetCenterFriendRecordList(&lstData, "pid = %u and gz_id > 0 and status < 255", pid);
	}
	
	//发送用户信息
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterPlayerInfoListPacket(&packet, pid, gz_id, lstData))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	Log.Debug("FriendGameRecordsManager::GetPlayerCenterInfo","pid[%u] gz_id[%u] lstData size[%u]", pid, gz_id, lstData.size());
	return true;
}

// 读取统计信息 2018-03-14
bool FriendGameRecordsManager::GetPlayerCenterInfo(CharPtr & pChr, const uint32 & pid, std::map<uint32, uint32> mapGzidMode)
{
	if(pChr.isNull() || mapGzidMode.empty())
		return false;
	
	std::list<CenterFriendRecord> lstData;
	std::vector<stGzidSampleCountInfo> vGSCI;
	std::map<uint32, uint32>::iterator iter, ei = mapGzidMode.end();
	for(iter = mapGzidMode.begin(); iter!=ei; ++iter)
	{
		std::list<CenterFriendRecord> queryData;
		if(iter->second != 0)
		{// 所有玩法
			GetCenterFriendRecordList(&queryData,"gz_id = %u and data1 = %u and  pid = %u and status < 255", iter->first, iter->second, pid);
		}
		else
		{// 指定玩法
			GetCenterFriendRecordList(&queryData, "pid = %u and gz_id = %u and status < 255", pid, iter->first);
		}
		
		if(queryData.size())
			lstData.insert(lstData.end(), queryData.begin(), queryData.end());
	}
	
	std::list<CenterFriendRecord>::iterator itData, eiData = lstData.end();
	for(itData = lstData.begin(); itData!=eiData; ++itData)
	{
		stGzidSampleCountInfo stGSCI;
		stGSCI.gz_id = (*itData).gz_id;
		
		std::map<uint32, uint32>::iterator fit = mapGzidMode.find((*itData).gz_id);
		if(fit == mapGzidMode.end())
			continue;
		
		stGSCI.mode = fit->second;
		
		Json::Value val;
		Json::Reader reader;
		reader.parse((*itData).record_data, val);
		
		if(val.empty())
			continue;
		
		if(!val.isMember("normal") || !val.isMember("hide"))
			continue;
		
		if(!val["normal"].isMember("total_count") || !val["hide"].isMember("win_count"))
			continue;
		
		stGSCI.zcs = val["normal"]["total_count"].asUInt();
		stGSCI.slcs = val["hide"]["win_count"].asUInt();
		
		Log.Debug("FriendGameRecordsManager::GetPlayerCenterInfo","gz_id[%u] zcs[%u] slcs[%u]", (*itData).gz_id, stGSCI.zcs, stGSCI.slcs);
		
		if(fit->second == 0)
		{
			bool bFind = false;
			std::vector<stGzidSampleCountInfo>::iterator itV, eiV = vGSCI.end();
			for(itV = vGSCI.begin(); itV!=eiV; ++itV)
			{	
				if((*itV).gz_id == (*itData).gz_id && (*itV).mode == fit->second)
				{
					(*itV).zcs += stGSCI.zcs;
					(*itV).slcs += stGSCI.slcs;
					
					bFind = true;
					break;
				}
			}
			
			if(!bFind)
				vGSCI.push_back(stGSCI);
		}
	}
	
	if(vGSCI.size() < mapGzidMode.size())
	{// 返回的记录数量不足，补足空的数量
		std::map<uint32, uint32>::iterator itM, eiM = mapGzidMode.end();
		for(itM = mapGzidMode.begin(); itM!=eiM; ++itM)
		{
			bool bFind = false;
			for(uint8 i=0; i<vGSCI.size(); ++i)
			{
				if(vGSCI[i].gz_id == itM->first && vGSCI[i].mode == itM->second)
				{
					bFind = true;
					break;
				}
			}
			
			if(!bFind)
			{
				stGzidSampleCountInfo stGSCI;
				stGSCI.gz_id = itM->first;
				stGSCI.mode = itM->second;
				
				vGSCI.push_back(stGSCI);
			}	
		}
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCenterPlayerCountInfoPacket(&packet, pid, vGSCI))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
	
	return true;
}

// 获取玩家统计数据
bool FriendGameRecordsManager::GetPlayerRecordInfo(CharPtr & pChr, CenterFriendRecord & cfr, const uint8 & mode)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint8 real_mode = mode % 100;
	uint32 pid = pUser->getUInt32Field("platform_id");
	uint32 gz_id = pUser->getUInt32Field("gz_id");
	
	std::list<CenterFriendRecord> lstData;
	GetCenterFriendRecordList(&lstData,"pid = %u and gz_id = %u and data1 = %u and status < 255", pid, gz_id, real_mode);
	
	if(lstData.empty())
		return false;
	
	cfr = *lstData.begin();
	return true;
}

// 保存玩家游戏配置
bool FriendGameRecordsManager::SavePlayerGameConfig(CharPtr & pChr, String & config)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	std::list<CenterFriendRecord> lstData;
	GetCenterFriendRecordList(&lstData,"pid = %u and gz_id = %u and status < 255", pid, 0);
	
	if(lstData.empty())
	{// 创建并提交记录
		CenterFriendRecord cFR;
		
		cFR.group_id = sChannelMgr.getGroupID();
		cFR.status = 1;
		cFR.pid = pid;
		cFR.gz_id = 0;
		cFR.lu_timer = time(0);
		cFR.sdata1 = config;
		
		AddCenterFriendRecord(cFR);
	}
	else
	{// 更新记录
		
		CenterFriendRecord cFR = *lstData.begin();
		cFR.lu_timer = time(0);
		cFR.sdata1 = config;
		
		UpdateCenterFriendRecord(cFR);
	}
	
	return true;
}

// 读取玩家游戏配置
String FriendGameRecordsManager::GetPlayerGameConfig(CharPtr & pChr)
{
	if(pChr.isNull())
		return "";
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return "";
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	std::list<CenterFriendRecord> lstData;
	if(!GetCenterFriendRecordList(&lstData,"pid = %u and gz_id = %u and status < 255", pid, 0))
		return "";
	
	return lstData.front().sdata1;
}

//=============================好友记录信息相关===================================


//=============================游戏聊天群组信息===================================

// 添加群组信息
bool ChatGroupManager::AddChatGroup(ChatGroup & cg)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPINFO, &fields);
	
	fields["agent_id"] = cg.agent_id;						
	fields["game_id"] = cg.game_id;					
	fields["gz_id"] = cg.gz_id;					
	fields["status"] = cg.status;	
	fields["create_pid"] = cg.create_pid;
	
	fields["owner_pid"] = cg.owner_pid;	
	fields["owner_name"] = cg.owner_name;
	fields["name"] = cg.name;
	fields["notice"] = cg.notice;
	
	fields["max_num"] = cg.max_num;
	fields["curr_num"] = cg.curr_num;
	fields["require_num"] = cg.require_num;
	fields["create_time"] = cg.create_time;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPINFO, &fields))
		return false;
	
	cg.chat_group_id = fields["chat_group_id"].GetUInt64();
	return true;
}

// 更新群组信息
bool ChatGroupManager::UpdateChatGroup(const ChatGroup & cg)
{
	Fields fields;
	fields["status"] = cg.status;				
	fields["owner_pid"] = cg.owner_pid;					
	fields["owner_name"] = cg.owner_name;					
	fields["name"] = cg.name;	
	fields["max_num"] = cg.max_num;
	fields["require_num"] = cg.require_num;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPINFO, &fields, "`chat_group_id` = %u", cg.chat_group_id);
	
	return count > 0;
}

bool ChatGroupManager::UpdateChatGroup(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPINFO, fields, sql);
	return count > 0;
}

bool ChatGroupManager::UpdateChatGroup(const uint64 &cg_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPINFO, fields, "`chat_group_id` = %u", cg_id);
	return count > 0;
}

// 获得群组信息
bool ChatGroupManager::GetChatGroup(const uint64 &cg_id, ChatGroup * cg)
{
	assert (cg);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &rows, "`chat_group_id` = %u", cg_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cg->chat_group_id = fields["chat_group_id"].GetUInt64();
	cg->agent_id = fields["agent_id"].GetUInt32();
	cg->game_id = fields["game_id"].GetUInt32();
	cg->gz_id = fields["gz_id"].GetUInt32();
	cg->status = fields["status"].GetUInt32();
	cg->create_pid = fields["create_pid"].GetUInt32();
	
	cg->owner_pid = fields["owner_pid"].GetUInt32();
	cg->owner_name = fields["owner_name"].GetValue();
	cg->name = fields["name"].GetValue();
	cg->notice = fields["notice"].GetValue();
	
	cg->max_num = fields["max_num"].GetUInt32();
	cg->curr_num = fields["curr_num"].GetUInt32();
	cg->require_num = fields["require_num"].GetUInt32();
	cg->create_time = fields["create_time"].GetValue();
	
	return true;
}

// 获得群组列表信息
uint32 ChatGroupManager::GetChatGroupList(std::list<ChatGroup> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		ChatGroup cg;
		Fields &fields = *iter;
		
		cg.chat_group_id = fields["chat_group_id"].GetUInt64();
		cg.agent_id = fields["agent_id"].GetUInt32();
		cg.game_id = fields["game_id"].GetUInt32();
		cg.gz_id = fields["gz_id"].GetUInt32();
		cg.status = fields["status"].GetUInt32();
		cg.create_pid = fields["create_pid"].GetUInt32();
		
		cg.owner_pid = fields["owner_pid"].GetUInt32();
		cg.owner_name = fields["owner_name"].GetValue();
		cg.name = fields["name"].GetValue();
		cg.notice = fields["notice"].GetValue();
		
		cg.max_num = fields["max_num"].GetUInt32();
		cg.curr_num = fields["curr_num"].GetUInt32();
		cg.require_num = fields["require_num"].GetUInt32();
		cg.create_time = fields["create_time"].GetValue();
		
		lstData->push_back(cg);
	}
	
	return lstData->size();
}

// 创建群
uint8 ChatGroupManager::CreateChatGroup(CharPtr & pChr, String name)
{
	if(pChr.isNull())
		return enCreateChatGroupResult_Failed;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return enCreateChatGroupResult_Failed;
	
	if(name == "")	// 群名不能为空
		return enCreateChatGroupResult_EmptyName;
	
	// 先判断玩家创建的群是否达到上限
	std::list<ChatGroupPlayer> lstData;
	uint32 create_num = sChatGroupPlayerMgr.GetChatGroupPlayerList(&lstData, "type = %u and status < 255", enChatGroupMemberType_Owner);
	if(create_num >= sXmlDataMgr.GetConfXMLValue("MAX_GROUP_CREATENUM"))
		return enCreateChatGroupResult_CreateMax;
	
	// 创建群消息
	ChatGroup cg;
	cg.agent_id  = pUser->getUInt32Field("reg_from");			// 代理商ID
	// uint32 game_id;											// 游戏ID
	cg.gz_id = pUser->getUInt32Field("gz_id");					// 分区ID
	cg.status = 0;												// 群状态
	cg.create_pid = pUser->getUInt32Field("platform_id");		// 创建者玩家PID
	cg.owner_pid = pUser->getUInt32Field("platform_id");		// 群主PID
	cg.owner_name = pUser->getStringField("nick");				// 群主昵称

	cg.name = name;												// 群名称
	cg.notice = "";												// 公告信息

	cg.max_num = 50;											// 最大人数
	cg.curr_num = 1;											// 当前人数
	cg.require_num = 0;											// 申请数量
	
	cg.create_time = sGLMgr.GetCurDateTime();					// 群创建时间
	
	bool bCreateSucess = AddChatGroup(cg);
	
	if(bCreateSucess)
	{// 群创建成功，将群主加入群
		
		// 生成群主成员信息
		ChatGroupPlayer cgp;
		cgp.chat_group_id = cg.chat_group_id;				// 群组ID
		cgp.status = 1;										// 状态（0 申请 1 成员 255 删除）
		cgp.type = enChatGroupMemberType_Owner;				// 类型（0 普通成员 1 管理员 2 群主）
		cgp.pid = pUser->getUInt32Field("platform_id");		// 玩家PID
		
		cgp.nick = pChr->getStringField("name");			// 玩家昵称
		cgp.head_url = pChr->getStringField("desc");		// 头像地址
		
		cgp.create_time = sGLMgr.GetCurDateTime();
		sChatGroupPlayerMgr.AddChatGroupPlayer(cgp);
	}
	
	return bCreateSucess;
}

// 解散群
uint8 ChatGroupManager::DeleteChatGroup(CharPtr & pChr, const uint64 & chat_group_id)
{
	if(pChr.isNull())
		return 0;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("uid"));
	if(pUser.isNull())
		return 0;
	
	// 检查群是否存在
	ChatGroup cg;
	if(!GetChatGroup(chat_group_id, &cg))
		return 0;
	
	// 检查要操作的群，是否是自己
	uint32 my_pid = pUser->getUInt32Field("platform_id");
	if(cg.owner_pid != my_pid)
		return 0;
	
	// 取得群玩家列表
	std::list<ChatGroupPlayer> lstData;
	uint32 player_num = sChatGroupPlayerMgr.GetChatGroupPlayerList(&lstData, "chat_group_id = %u and status < 255 ", chat_group_id);
	if(!player_num)
		return 0;
	
	String szTitle = "";
	char buf[256] = "";
	
	std::map<uint32, uint32> mapItems;
	const MailModel *pModel = sXmlDataMgr.GetMailModel("CHAT_GROUP_DISSOLVE");
	if(pModel)
	{
		szTitle = pModel->szTitle;
		String szContent = pModel->szContent;
		
		//  群主【%s】将群【%s】于%s解散了。
		sprintf(buf, szContent.c_str(), pChr->getStringField("name").c_str(), cg.name.c_str(), sGLMgr.GetCurDateTime().c_str());
	}
		
	std::list<ChatGroupPlayer>::iterator iter, ei = lstData.end();
	for(iter = lstData.begin(); iter!=ei; ++iter)
	{
		(*iter).status = 255;
		
		sGLMgr.CreateMail((*iter).pid, szTitle, buf, 0, en_ST_ReturnCenterBattleOpenCoins, &mapItems);
		
		sChatGroupPlayerMgr.UpdateChatGroupPlayer(*iter);
	}
	
	cg.status = 255;
	return UpdateChatGroup(cg);
}

// 修改群消息（名称，公告）
uint8 ChatGroupManager::ChangeChatGroupInfo(CharPtr & pChr, const uint64 & chat_group_id, const uint32 & type, String & strData)
{
	if(pChr.isNull())
		return 0;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("uid"));
	if(pUser.isNull())
		return 0;
	
	// 检查群是否存在
	ChatGroup cg;
	if(!GetChatGroup(chat_group_id, &cg))
		return 0;
	
	// 检查要操作的群，是否是自己
	uint32 my_pid = pUser->getUInt32Field("platform_id");
	if(cg.owner_pid != my_pid)
		return 0;
	
	// 过滤非法字符
	StringUtil::trim(strData);
	
	if(type == enOpChatGroupType_ChangeName)
	{// 修改群名称
		cg.name = strData;
	}
	else if(type == enOpChatGroupType_ChangeNotice)
	{// 修改群公告
		cg.notice = strData;
	}
	else
	{// 目前不支持其他操作
		return 0;
	}
	
	return UpdateChatGroup(cg);
}

//=============================游戏聊天群组信息===================================


//=============================聊天群成员信息===================================

// 添加群组信息
bool ChatGroupPlayerManager::AddChatGroupPlayer(ChatGroupPlayer & cg)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPPLAYER, &fields);
	
	fields["chat_group_id"] = cg.chat_group_id;						
	fields["status"] = cg.status;					
	fields["type"] = cg.type;					
	fields["pid"] = cg.pid;	
	fields["nick"] = cg.nick;
	fields["head_url"] = cg.head_url;	
	fields["create_time"] = cg.create_time;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPPLAYER, &fields))
		return false;
	
	cg.group_player_id = fields["group_player_id"].GetUInt64();
	return true;
}

// 更新群组信息
bool ChatGroupPlayerManager::UpdateChatGroupPlayer(const ChatGroupPlayer & cg)
{
	Fields fields;
	fields["status"] = cg.status;
	fields["type"] = cg.type;
	fields["nick"] = cg.nick;
	fields["head_url"] = cg.head_url;
	fields["create_time"] = cg.create_time;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPPLAYER, &fields, "`group_player_id` = %u", cg.group_player_id);
	
	return count > 0;
}

bool ChatGroupPlayerManager::UpdateChatGroupPlayer(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPPLAYER, fields, sql);
	return count > 0;
}

bool ChatGroupPlayerManager::UpdateChatGroupPlayer(const uint32 &cg_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CHATGROUPPLAYER, fields, "`group_player_id` = %u", cg_id);
	return count > 0;
}

// 获得群组信息
bool ChatGroupPlayerManager::GetChatGroupPlayer(const uint32 &cg_id, ChatGroupPlayer * cg)
{
	assert (cg);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &rows, "`group_player_id` = %u", cg_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cg->group_player_id = fields["group_player_id"].GetUInt64();
	cg->chat_group_id = fields["chat_group_id"].GetUInt64();
	cg->status = fields["status"].GetUInt32();
	cg->type = fields["type"].GetUInt32();
	cg->pid = fields["pid"].GetUInt32();
	
	cg->nick = fields["nick"].GetValue();
	cg->head_url = fields["head_url"].GetValue();
	cg->create_time = fields["create_time"].GetValue();
	
	return true;
}

// 获得群组列表信息
uint32 ChatGroupPlayerManager::GetChatGroupPlayerList(std::list<ChatGroupPlayer> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERRECORD, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		ChatGroupPlayer cg;
		Fields &fields = *iter;
		
		cg.group_player_id = fields["group_player_id"].GetUInt64();
		cg.chat_group_id = fields["chat_group_id"].GetUInt64();
		cg.status = fields["status"].GetUInt32();
		cg.type = fields["type"].GetUInt32();
		cg.pid = fields["pid"].GetUInt32();
		
		cg.nick = fields["nick"].GetValue();
		cg.head_url = fields["head_url"].GetValue();
		cg.create_time = fields["create_time"].GetValue();
		
		lstData->push_back(cg);
	}
	
	return lstData->size();
}



//=============================聊天群成员信息===================================
